﻿using System;
using Gwn.Library.MvpVm.Entities;
using Gwn.Library.MvpVm.Events;
using Gwn.Module.UserManager.Interfaces;
using Gwn.Module.UserManager.Types;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Unity;

namespace Gwn.Module.UserManager.Layers
{
    /// <summary>
    /// BLL provides a friendly fascade for a generic IDataAccessLayer interface
    /// </summary>
    public class MockBll : IBusinessLogicLayer 
    {
        /// <summary>
        /// Gets or sets the dal.
        /// </summary>
        /// <value>The dal.</value>
        [Dependency]
        public IDataAccessLayer Dal { get; set; }

        [Dependency]
        public IEventAggregator EventAggregator { get; set; }

        /// <summary>
        /// Gets the user list async.
        /// </summary>
        public void GetUserListAsync()
        {
            try
            {
                Dal.ListData();
            }
            catch(Exception ex)
            {
                PublishMessage(ex, new User());
            }
        }

        /// <summary>
        /// Creates the user async.
        /// </summary>
        /// <param name="record">The record.</param>
        public void CreateUserAsync(User record)
        {
            try
            {
                bool isValidationError = false;

                if (record == null)
                    isValidationError = PublishMessage("No user record was provided!", record);

                if (string.IsNullOrEmpty(record.FirstName) || isValidationError)
                    isValidationError = PublishMessage("You must provide a first name!", record);

                if (string.IsNullOrEmpty(record.FirstName) || isValidationError)
                    isValidationError = PublishMessage("You must provide a first name!", record);

                if (isValidationError)
                    return;

                Dal.Create(this, GetArgs(UserManagerProcessType.CreateData, record));
            }
            catch(Exception ex)
            {
                PublishMessage(ex, record);
            }
        }

        /// <summary>
        /// Reads the user async.
        /// </summary>
        /// <param name="record">The record.</param>
        public void ReadUserAsync(User record)
        {
            try
            {
                if (record == null || record.Id == 0)
                    PublishMessage("You must provide a valid user record!", record);
                else
                    Dal.Read(this, GetArgs(UserManagerProcessType.ReadData, record));
            }
            catch(Exception ex)
            {
                PublishMessage(ex, record);
            }
        }

        /// <summary>
        /// Updates the user async.
        /// </summary>
        /// <param name="record">The record.</param>
        public void UpdateUserAsync(User record)
        {
            try
            {
                bool isValidationError = false;

                if (record == null)
                    isValidationError = PublishMessage("No user record was provided!", record);

                if (string.IsNullOrEmpty(record.FirstName) || isValidationError)
                    isValidationError = PublishMessage("You must provide a first name!", record);

                if (string.IsNullOrEmpty(record.FirstName) || isValidationError)
                    isValidationError = PublishMessage("You must provide a first name!", record);

                if (isValidationError)
                    return;

                Dal.Update(this, GetArgs(UserManagerProcessType.UpdateData, record));
            }
            catch(Exception ex)
            {
                PublishMessage(ex, record);
            }
        }

        /// <summary>
        /// Deletes the user async.
        /// </summary>
        /// <param name="record">The record.</param>
        public void DeleteUserAsync(User record)
        {
            try
            {
                if (record == null || record.Id == 0)
                    PublishMessage("You must provide a valid user record!", record);
                else
                    Dal.Delete(this, GetArgs(UserManagerProcessType.DeleteData, record));
            }
            catch(Exception ex)
            {
                PublishMessage(ex, record);
            }
        }





        private bool PublishMessage(string exceptionMessage, User record)
        {
            var args = new ProcessEventArgs
                           {
                               Data = record,
                               Exception = new Exception(exceptionMessage),
                               ProcessType = UserManagerProcessType.MessageOnly
                           };
            // Publish the error message
            EventAggregator.GetEvent<ProcessEvent>().Publish(args);
            return true;
        }

        private bool PublishMessage(Exception exception, User record)
        {
            var args = new ProcessEventArgs
                           {
                               Data = record,
                               Exception = exception,
                               FriendlyMessage = exception.Message + exception.StackTrace
                           };

            // Publish the error message
            EventAggregator.GetEvent<ProcessEvent>().Publish(args);

            return true;
        }


        private ProcessEventArgs GetArgs(UserManagerProcessType processType, User record)
        {
            return new ProcessEventArgs
            {
                Data = record,
                ProcessType = processType
            };
        }

    }
}
